#include<iostream>
#include<cuda_runtime.h>
#include<vector>
#include "../MyTimer.h"
#include<string>
#include<math.h>
#include<sstream>
#include <cusparse.h>


float** init(int m, int n)
{
    float** f = new float*[m];
    for(int i = 0; i < m; i++)
    {
        f[i] = new float[n];
        for(int j = 0; j < n; j++)
        {
            f[i][j] = (rand()%2) * (rand()%10);
        }
    }
    return f;
}
void show(float**f, int m, int n)
{
    for(int i = 0; i < m; i++)
    {
        for(int j = 0; j < n; j++)
        {
            std::cout<<f[i][j]<<" ";
        }
        std::cout<<std::endl;
    }
}
int get_nnz(float** f, int m, int n)
{
    int nnz = 0;
    for(int i = 0; i < m; i++)
    {
        for(int j = 0; j < n; j++){
            if(f[i][j] != 0) nnz++;
        }
    }
    return nnz;
}

int main()
{
    int m = 1 << 4, n = 1 << 4;
    float**f = init(m, n);
    show(f, m, n);
    int nnz = get_nnz(f, m, n);

    float* COOval = new float[nnz], *d_COOval;
    int *COO_row = new int[nnz], *d_COO_row, *COO_col = new int[nnz], *d_COO_col;
    int temp = 0;
    for(int i = 0; i < m; i++)
    {
        for(int j = 0 ; j < n; j++)
        {
            if(f[i][j] != 0)
            {
                COOval[temp] = f[i][j];
                COO_row[temp] = i;
                COO_col[temp] = j;
                temp++;
            }
        }
    }

    int nnzBs_f = nnz * sizeof(float);
    int nnzBs_i = nnz * sizeof(int);
    cudaMalloc((void**)&d_COOval, nnzBs_f);
    cudaMalloc((void**)&d_COO_row, nnzBs_i);
    cudaMalloc((void**)&d_COO_col, nnzBs_i);

    cudaMemcpy(d_COOval, COOval, nnzBs_f, cudaMemcpyHostToDevice);
    cudaMemcpy(d_COO_row, COO_row, nnzBs_i, cudaMemcpyHostToDevice);
    cudaMemcpy(d_COO_col, COO_col, nnzBs_i, cudaMemcpyHostToDevice);





    // float* CSRval = new float[nnz], d_CSRval;
    // int *CSR_row = new int[m + 1], d_CSR_row, CSR_col = new int[nnz], d_CSR_col;
    float * d_CSRval;
    int *d_CSR_row, *d_CSR_row2, *d_CSR_col;
    cudaMalloc((void**)&d_COOval, nnzBs_f);
    cudaMalloc((void**)&d_CSR_row, sizeof(int) * (m + 1));
    cudaMalloc((void**)&d_CSR_row2, sizeof(int) * (m + 1));
    cudaMalloc((void**)&d_CSR_col, nnzBs_i);


    cusparseMatDescr_t descr;
    cusparseCreateMatDescr(&descr);
    cusparseSetMatType(descr, CUSPARSE_MATRIX_TYPE_GENERAL);
    cusparseSetMatIndexBase(descr, CUSPARSE_INDEX_BASE_ZERO);
    
    
    cusparseHandle_t handle;
    cusparseCreate(&handle);

    float* d_matrix;
    cudaMalloc((void**)&d_matrix, sizeof(float) * m * n);
    cudaMemcpy(d_matrix, f, sizeof(float) * m * n, cudaMemcpyHostToDevice);


    //方法一：直接把矩阵抓为CSR
    //cusparseSdense2csr(handle, m, n, descr, d_matrix, m, d_CSR_row, d_CSRval, d_CSR_col);


    //方法二：COO转CSR
    cusparseXcoo2csr(handle, d_COO_row, nnz, m, d_CSR_row2, CUSPARSE_INDEX_BASE_ZERO);
    



}





















